home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / DirectX SDK / DXSDK / samples / Multimedia / DirectShow_WinXP / VMR / Renderless / app.cpp < prev    next >
C/C++ Source or Header  |  2001-10-08  |  27KB  |  996 lines

  1. //------------------------------------------------------------------------------
  2. // File: app.cpp
  3. //
  4. // Desc: DirectShow sample code - VMR-based Renderless video player
  5. //
  6. // Copyright (c) 1994 - 2001, Microsoft Corporation.  All rights reserved.
  7. //------------------------------------------------------------------------------
  8.  
  9. #include <streams.h>
  10. #include <atlbase.h>
  11. #include <atlconv.cpp>
  12. #include <mmreg.h>
  13. #include <commctrl.h>
  14.  
  15. #include <initguid.h>
  16. #include "project.h"
  17. #include "resource.h"
  18.  
  19. #include <stdarg.h>
  20. #include <stdio.h>
  21.  
  22. #include <initguid.h>
  23.  
  24. /* -------------------------------------------------------------------------
  25. ** Global variables that are initialized at run time and then stay constant.
  26. ** -------------------------------------------------------------------------
  27. */
  28. HINSTANCE           hInst;
  29. HICON               hIconVideoCd;
  30. HWND                hwndApp;
  31. HWND                g_hwndToolbar;
  32. CMpegMovie          *pMpegMovie;
  33.  
  34. BOOL m_bFullScreen = FALSE;
  35.  
  36. /* -------------------------------------------------------------------------
  37. ** True Globals - these may change during execution of the program.
  38. ** -------------------------------------------------------------------------
  39. */
  40. TCHAR g_achFileName[MAX_PATH];
  41. DWORD g_State = VCD_NO_CD;
  42.  
  43. /* -------------------------------------------------------------------------
  44. ** Constants
  45. ** -------------------------------------------------------------------------
  46. */
  47. const TCHAR szClassName[] = TEXT("VMR_RenderlessPlayer_CLASS");
  48. const TCHAR g_szNULL[]    = TEXT("\0");
  49. const TCHAR g_szEmpty[]   = TEXT("");
  50.  
  51. /*
  52. ** User interface values
  53. */
  54.       int   dyToolbar;
  55. const int   dxBitmap        = 16;
  56. const int   dyBitmap        = 15;
  57. const int   dxButtonSep     = 8;
  58. const TCHAR g_chNULL        = TEXT('\0');
  59. const LONG  g_Style         = WS_THICKFRAME | WS_POPUP | WS_CAPTION  |
  60.                               WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX |
  61.                               WS_CLIPCHILDREN;
  62.  
  63.  
  64. const TBBUTTON tbButtons[DEFAULT_TBAR_SIZE] = {
  65.     { IDX_SEPARATOR,    1,                    0,               TBSTYLE_SEP           },
  66.     { IDX_1,            IDM_MOVIE_PLAY,       TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  67.     { IDX_2,            IDM_MOVIE_PAUSE,      TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  68.     { IDX_3,            IDM_MOVIE_STOP,       TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  69.     { IDX_SEPARATOR,    1,                    0,               TBSTYLE_SEP           },
  70.     { IDX_4,            IDM_FULL_SCREEN,      TBSTATE_ENABLED, TBSTYLE_CHECK,  0, 0, 0, -1 }
  71. };
  72.  
  73.  
  74. /* -------------------------------------------------------------------------
  75. ** Local function prototypes
  76. ** -------------------------------------------------------------------------
  77. */
  78. void SetFullScreenMode(BOOL bMode);
  79. BOOL IsFullScreenMode();
  80. LRESULT CALLBACK AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
  81.  
  82.  
  83. /******************************Public*Routine******************************\
  84. * WinMain
  85. *
  86. *
  87. * Windows recognizes this function by name as the initial entry point
  88. * for the program.  This function calls the application initialization
  89. * routine, if no other instance of the program is running, and always
  90. * calls the instance initialization routine.  It then executes a message
  91. * retrieval and dispatch loop that is the top-level control structure
  92. * for the remainder of execution.  The loop is terminated when a WM_QUIT
  93. * message is received, at which time this function exits the application
  94. * instance by returning the value passed by PostQuitMessage().
  95. *
  96. * If this function must abort before entering the message loop, it
  97. * returns the conventional value NULL.
  98. *
  99. \**************************************************************************/
  100. int PASCAL
  101. WinMain(
  102.     HINSTANCE hInstance,
  103.     HINSTANCE hPrevInstance,
  104.     LPSTR lpCmdLineOld,
  105.     int nCmdShow
  106.     )
  107. {
  108.     USES_CONVERSION;
  109.     LPTSTR lpCmdLine = A2T(lpCmdLineOld);
  110.  
  111.     HRESULT hres = CoInitialize(NULL);
  112.     if(hres == S_FALSE)
  113.     {
  114.         CoUninitialize();
  115.     }
  116.  
  117.     if(!hPrevInstance)
  118.     {
  119.         if(!InitApplication(hInstance))
  120.         {
  121.             return FALSE;
  122.         }
  123.     }
  124.  
  125.     /*
  126.     ** Perform initializations that apply to a specific instance
  127.     */
  128.     if(!InitInstance(hInstance, nCmdShow))
  129.     {
  130.         return FALSE;
  131.     }
  132.  
  133.     /* Verify that the VMR is present on this system */
  134.     if(!VerifyVMR())
  135.         return FALSE;
  136.  
  137.     /*
  138.     ** Acquire and dispatch messages until a WM_QUIT message is received.
  139.     */
  140.     int iRet = DoMainLoop();
  141.     QzUninitialize();
  142.     return iRet;
  143. }
  144.  
  145.  
  146. /*****************************Private*Routine******************************\
  147. * DoMainLoop
  148. *
  149. * Process the main message loop
  150. *
  151. \**************************************************************************/
  152. int
  153. DoMainLoop(
  154.     void
  155.     )
  156. {
  157.     MSG         msg;
  158.     HANDLE      ahObjects[8];;
  159.     int         cObjects;
  160.     HACCEL      haccel = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATOR));
  161.  
  162.     //
  163.     // message loop lasts until we get a WM_QUIT message
  164.     //
  165.     for(;;)
  166.     {
  167.         if(pMpegMovie != NULL)
  168.         {
  169.             cObjects = 1;
  170.             ahObjects[0] = pMpegMovie->GetMovieEventHandle();
  171.         }
  172.         else
  173.         {
  174.             ahObjects[0] = NULL;
  175.             cObjects = 0;
  176.         }
  177.  
  178.         if(ahObjects[0] == NULL)
  179.         {
  180.             WaitMessage();
  181.         }
  182.         else
  183.         {
  184.             //
  185.             // wait for any message sent or posted to this queue
  186.             // or for a graph notification
  187.             //
  188.             DWORD result;
  189.  
  190.             result = MsgWaitForMultipleObjects(cObjects, ahObjects, FALSE,
  191.                 INFINITE, QS_ALLINPUT);
  192.             if(result != (WAIT_OBJECT_0 + cObjects))
  193.             {
  194.  
  195.                 VideoCd_OnGraphNotify(result - WAIT_OBJECT_0);
  196.  
  197.                 continue;
  198.             }
  199.         }
  200.  
  201.         //
  202.         // When here, we either have a message or no event handle
  203.         // has been created yet.
  204.         //
  205.         // read all of the messages in this next loop
  206.         // removing each message as we read it
  207.         //
  208.         while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  209.         {
  210.             if(msg.message == WM_QUIT)
  211.             {
  212.                 return (int) msg.wParam;
  213.             }
  214.  
  215.             if(!TranslateAccelerator(hwndApp, haccel, &msg))
  216.             {
  217.                 TranslateMessage(&msg);
  218.                 DispatchMessage(&msg);
  219.             }
  220.         }
  221.     }
  222.  
  223. } // DoMainLoop
  224.  
  225.  
  226. /*****************************Private*Routine******************************\
  227. * InitApplication(HANDLE)
  228. *
  229. * This function is called at initialization time only if no other
  230. * instances of the application are running.  This function performs
  231. * initialization tasks that can be done once for any number of running
  232. * instances.
  233. *
  234. * In this case, we initialize a window class by filling out a data
  235. * structure of type WNDCLASS and calling the Windows RegisterClass()
  236. * function.  Since all instances of this application use the same window
  237. * class, we only need to do this when the first instance is initialized.
  238. *
  239. \**************************************************************************/
  240. BOOL
  241. InitApplication(
  242.     HINSTANCE hInstance
  243.     )
  244. {
  245.     WNDCLASS  wc;
  246.  
  247.     /*
  248.     ** Fill in window class structure with parameters that describe the
  249.     ** main window.
  250.     */
  251.     hIconVideoCd     = LoadIcon(hInstance, MAKEINTRESOURCE(IDR_VIDEOCD_ICON));
  252.  
  253.     wc.style         = CS_VREDRAW | CS_HREDRAW;
  254.     wc.lpfnWndProc   = VideoCdWndProc;
  255.     wc.cbClsExtra    = 0;
  256.     wc.cbWndExtra    = 0;
  257.     wc.hInstance     = hInstance;
  258.     wc.hIcon         = hIconVideoCd;
  259.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  260.     wc.hbrBackground = (HBRUSH)NULL;
  261.     wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MAIN_MENU);
  262.     wc.lpszClassName = szClassName;
  263.  
  264.     /*
  265.     ** Register the window class and return success/failure code.
  266.     */
  267.     return RegisterClass(&wc);
  268. }
  269.  
  270.  
  271. /*****************************Private*Routine******************************\
  272. * InitInstance
  273. *
  274. * This function is called at initialization time for every instance of
  275. * this application.  This function performs initialization tasks that
  276. * cannot be shared by multiple instances.
  277. *
  278. * In this case, we save the instance handle in a static variable and
  279. * create and display the main program window.
  280. *
  281. \**************************************************************************/
  282. BOOL
  283. InitInstance(
  284.     HINSTANCE hInstance,
  285.     int nCmdShow
  286.     )
  287. {
  288.     HWND    hwnd;
  289.     RECT    rc;
  290.  
  291.     /*
  292.     ** Save the instance handle in static variable, which will be used
  293.     ** in many subsequent calls to Windows.
  294.     */
  295.     hInst = hInstance;
  296.     rc.left = rc.top = 100;
  297.     rc.bottom = rc.right = 400;
  298.  
  299.     /*
  300.     ** Create a main window for this application instance.
  301.     */
  302.     hwnd = CreateWindow(szClassName, IdStr(STR_APP_TITLE), g_Style,
  303.         rc.left, rc.top,
  304.         rc.right, rc.bottom,
  305.         NULL, NULL, hInstance, NULL);
  306.  
  307.     /*
  308.     ** If window could not be created, return "failure"
  309.     */
  310.     if(NULL == hwnd)
  311.     {
  312.         return FALSE;
  313.     }
  314.     hwndApp = hwnd;
  315.  
  316.     /*
  317.     ** Make the window visible; update its client area; and return "success"
  318.     */
  319.     SetPlayButtonsEnableState();
  320.     ShowWindow(hwnd, nCmdShow);
  321.     UpdateWindow(hwnd);
  322.  
  323.     return TRUE;
  324. }
  325.  
  326.  
  327. /*****************************Private*Routine******************************\
  328. * GetMoviePosition
  329. *
  330. * Place the movie in the centre of the client window.  
  331. * We do not stretch the the movie yet.
  332. *
  333. \**************************************************************************/
  334. void
  335. GetMoviePosition(
  336.     HWND hwnd,
  337.     long* xPos,
  338.     long* yPos,
  339.     long* pcx,
  340.     long* pcy
  341.     )
  342. {
  343.     RECT rc;
  344.  
  345.     GetAdjustedClientRect(&rc);
  346.  
  347.     *xPos = rc.left;
  348.     *yPos = rc.top;
  349.     *pcx = rc.right - rc.left;
  350.     *pcy = rc.bottom - rc.top;
  351. }
  352.  
  353.  
  354. /******************************Public*Routine******************************\
  355. * RepositionMovie
  356. *
  357. \**************************************************************************/
  358. void
  359. RepositionMovie(HWND hwnd)
  360. {
  361.     if(pMpegMovie)
  362.     {
  363.         long xPos, yPos, cx, cy;
  364.  
  365.         GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
  366.  
  367.         pMpegMovie->PutMoviePosition(xPos, yPos, cx, cy);
  368.         InvalidateRect(hwnd, NULL, false);
  369.         UpdateWindow(hwnd);
  370.     }
  371. }
  372.  
  373.  
  374. /*****************************Private*Routine******************************\
  375. * VideoCd_OnMove
  376. *
  377. \**************************************************************************/
  378. void
  379. VideoCd_OnMove(
  380.     HWND hwnd,
  381.     int x,
  382.     int y
  383.     )
  384. {
  385.     if(pMpegMovie)
  386.     {
  387.         if(pMpegMovie->GetStateMovie() != State_Running)
  388.         {
  389.             RepositionMovie(hwnd);
  390.         }
  391.         else
  392.         {
  393.             long xPos, yPos, cx, cy;
  394.  
  395.             // Reposition movie but don't invalidate the rect, since
  396.             // the next video frame will handle the redraw.
  397.             GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
  398.             pMpegMovie->PutMoviePosition(xPos, yPos, cx, cy);
  399.         }
  400.     }
  401. }
  402.  
  403.  
  404. /******************************Public*Routine******************************\
  405. * VideoCdWndProc
  406. *
  407. \**************************************************************************/
  408. LRESULT CALLBACK
  409. VideoCdWndProc(
  410.     HWND hwnd,
  411.     UINT message,
  412.     WPARAM wParam,
  413.     LPARAM lParam
  414.     )
  415. {
  416.     switch(message)
  417.     {
  418.         HANDLE_MSG(hwnd, WM_CREATE,            VideoCd_OnCreate);
  419.         HANDLE_MSG(hwnd, WM_PAINT,             VideoCd_OnPaint);
  420.         HANDLE_MSG(hwnd, WM_COMMAND,           VideoCd_OnCommand);
  421.         HANDLE_MSG(hwnd, WM_CLOSE,             VideoCd_OnClose);
  422.         HANDLE_MSG(hwnd, WM_DESTROY,           VideoCd_OnDestroy);
  423.         HANDLE_MSG(hwnd, WM_SIZE,              VideoCd_OnSize);
  424.         HANDLE_MSG(hwnd, WM_SYSCOLORCHANGE,    VideoCd_OnSysColorChange);
  425.         HANDLE_MSG(hwnd, WM_INITMENUPOPUP,     VideoCd_OnInitMenuPopup);
  426.         HANDLE_MSG(hwnd, WM_NOTIFY,            VideoCd_OnNotify);
  427.         HANDLE_MSG(hwnd, WM_KEYUP,             VideoCd_OnKeyUp);
  428.         HANDLE_MSG(hwnd, WM_MOVE,              VideoCd_OnMove);
  429.  
  430.         case WM_DISPLAYCHANGE:
  431.         {
  432.             if(pMpegMovie)
  433.             {
  434.                 pMpegMovie->DisplayModeChanged();
  435.             }
  436.         }
  437.         break;
  438.  
  439.         default:
  440.             return DefWindowProc(hwnd, message, wParam, lParam);
  441.     }
  442.  
  443.     return 0L;
  444. }
  445.  
  446.  
  447. /*****************************Private*Routine******************************\
  448. * VideoCd_OnCreate
  449. *
  450. \**************************************************************************/
  451. BOOL
  452. VideoCd_OnCreate(
  453.     HWND hwnd,
  454.     LPCREATESTRUCT lpCreateStruct
  455.     )
  456. {
  457.     InitCommonControls();
  458.  
  459.     /*
  460.     ** Create the toolbar and statusbar.
  461.     */
  462.     g_hwndToolbar = CreateToolbarEx(hwnd,
  463.         WS_VISIBLE | WS_CHILD |
  464.         TBSTYLE_TOOLTIPS | CCS_NODIVIDER,
  465.         ID_TOOLBAR, NUMBER_OF_BITMAPS,
  466.         hInst, IDR_TOOLBAR, tbButtons,
  467.         DEFAULT_TBAR_SIZE, dxBitmap, dyBitmap,
  468.         dxBitmap, dyBitmap, sizeof(TBBUTTON));
  469.  
  470.     if(g_hwndToolbar == NULL)
  471.     {
  472.         return FALSE;
  473.     }
  474.  
  475.     return TRUE;
  476. }
  477.  
  478. /*****************************Private*Routine******************************\
  479. * VideoCd_OnKeyUp
  480. *
  481. \**************************************************************************/
  482. void
  483. VideoCd_OnKeyUp(
  484.     HWND hwnd,
  485.     UINT vk,
  486.     BOOL fDown,
  487.     int cRepeat,
  488.     UINT flags
  489.     )
  490. {
  491.     // Catch escape sequences to stop fullscreen mode
  492.     if((vk == VK_ESCAPE) || (vk == VK_RETURN))
  493.     {
  494.         if(pMpegMovie && IsFullScreenMode())
  495.         {
  496.             SetFullScreenMode(FALSE);
  497.             SetPlayButtonsEnableState();
  498.         }
  499.     }
  500. }
  501.  
  502. /*****************************Private*Routine******************************\
  503. * VideoCd_OnPaint
  504. *
  505. \**************************************************************************/
  506. void
  507. VideoCd_OnPaint(
  508.     HWND hwnd
  509.     )
  510. {
  511.     PAINTSTRUCT ps;
  512.     HDC         hdc;
  513.     RECT        rc1;
  514.     RECT        rc2;
  515.  
  516.     /*
  517.     ** Draw a frame around the movie playback area.
  518.     */
  519.     GetClientRect(hwnd, &rc2);
  520.  
  521.     hdc = BeginPaint(hwnd, &ps);
  522.  
  523.     if(pMpegMovie)
  524.     {
  525.         long xPos, yPos, cx, cy;
  526.         GetMoviePosition(hwnd, &xPos, &yPos, &cx, &cy);
  527.         SetRect(&rc1, xPos, yPos, xPos + cx, yPos + cy);
  528.  
  529.         HRGN rgnClient = CreateRectRgnIndirect(&rc2);
  530.         HRGN rgnVideo  = CreateRectRgnIndirect(&rc1);
  531.         CombineRgn(rgnClient, rgnClient, rgnVideo, RGN_DIFF);
  532.  
  533.         HBRUSH hbr = GetSysColorBrush(COLOR_BTNFACE);
  534.         FillRgn(hdc, rgnClient, hbr);
  535.         DeleteObject(hbr);
  536.         DeleteObject(rgnClient);
  537.         DeleteObject(rgnVideo);
  538.  
  539.         pMpegMovie->RepaintVideo(hwnd, hdc);
  540.     }
  541.     else
  542.     {
  543.         FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE + 1));
  544.     }
  545.  
  546.     EndPaint(hwnd, &ps);
  547. }
  548.  
  549.  
  550. LRESULT CALLBACK AboutDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  551. {
  552.     switch(message)
  553.     {
  554.         case WM_INITDIALOG:
  555.             return TRUE;
  556.  
  557.         case WM_COMMAND:
  558.             if(wParam == IDOK)
  559.             {
  560.                 EndDialog(hWnd, TRUE);
  561.                 return TRUE;
  562.             }
  563.             break;
  564.     }
  565.     return FALSE;
  566. }
  567.  
  568.  
  569. /*****************************Private*Routine******************************\
  570. * VideoCd_OnCommand
  571. *
  572. \**************************************************************************/
  573. void
  574. VideoCd_OnCommand(
  575.     HWND hwnd,
  576.     int id,
  577.     HWND hwndCtl,
  578.     UINT codeNotify
  579.     )
  580. {
  581.     switch(id)
  582.     {
  583.         case IDM_FILE_OPEN:
  584.             if(VcdPlayerOpenCmd())
  585.                 VcdPlayerPlayCmd();
  586.             break;
  587.  
  588.         case IDM_FILE_CLOSE:
  589.             VcdPlayerCloseCmd();
  590.             QzFreeUnusedLibraries();
  591.             break;
  592.  
  593.         case IDM_FILE_ABOUT:
  594.             DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX),
  595.                 hwnd,  (DLGPROC) AboutDlgProc);
  596.             break;
  597.  
  598.         case IDM_FILE_EXIT:
  599.             PostMessage(hwnd, WM_CLOSE, 0, 0L);
  600.             break;
  601.  
  602.         case IDM_MOVIE_PLAY:
  603.             VcdPlayerPlayCmd();
  604.             break;
  605.  
  606.         case IDM_MOVIE_STOP:
  607.             VcdPlayerStopCmd();
  608.             VcdPlayerRewindCmd();
  609.             break;
  610.  
  611.         case IDM_MOVIE_PAUSE:
  612.             VcdPlayerPauseCmd();
  613.             break;
  614.  
  615.         case IDM_FULL_SCREEN:
  616.             if(pMpegMovie)
  617.             {
  618.                 BOOL bFullScreen = (BOOL)SendMessage(g_hwndToolbar,
  619.                     TB_ISBUTTONCHECKED, IDM_FULL_SCREEN, 0);
  620.                 SetFullScreenMode(bFullScreen);
  621.             }
  622.             break;
  623.     }
  624.  
  625.     SetPlayButtonsEnableState();
  626. }
  627.  
  628. /******************************Public*Routine******************************\
  629. * VideoCd_OnDestroy
  630. *
  631. \**************************************************************************/
  632. void
  633. VideoCd_OnDestroy(
  634.     HWND hwnd
  635.     )
  636. {
  637.     VideoCd_OnClose(hwnd);
  638.     PostQuitMessage(0);
  639. }
  640.  
  641. /******************************Public*Routine******************************\
  642. * VideoCd_OnClose
  643. *
  644. \**************************************************************************/
  645. void
  646. VideoCd_OnClose(
  647.     HWND hwnd
  648.     )
  649. {
  650.     VcdPlayerCloseCmd();
  651.     DestroyWindow(hwnd);
  652. }
  653.  
  654. /******************************Public*Routine******************************\
  655. * VideoCd_OnSize
  656. *
  657. \**************************************************************************/
  658. void
  659. VideoCd_OnSize(
  660.     HWND hwnd,
  661.     UINT state,
  662.     int dx,
  663.     int dy
  664.     )
  665. {
  666.     if(IsWindow(g_hwndToolbar))
  667.         SendMessage(g_hwndToolbar, WM_SIZE, 0, 0L);
  668.  
  669.     RepositionMovie(hwnd);
  670. }
  671.  
  672.  
  673. /*****************************Private*Routine******************************\
  674. * VideoCd_OnSysColorChange
  675. *
  676. \**************************************************************************/
  677. void
  678. VideoCd_OnSysColorChange(
  679.     HWND hwnd
  680.     )
  681. {
  682.     FORWARD_WM_SYSCOLORCHANGE(g_hwndToolbar, SendMessage);
  683. }
  684.  
  685. /*****************************Private*Routine******************************\
  686. * VideoCd_OnInitMenuPopup
  687. *
  688. \**************************************************************************/
  689. void
  690. VideoCd_OnInitMenuPopup(
  691.     HWND hwnd,
  692.     HMENU hMenu,
  693.     UINT item,
  694.     BOOL fSystemMenu
  695.     )
  696. {
  697.     UINT uFlags;
  698.  
  699.     if(item == 0)
  700.     { // File menu
  701.  
  702.         if(g_State & (VCD_IN_USE | VCD_NO_CD | VCD_DATA_CD_LOADED))
  703.         {
  704.             uFlags = (MF_BYCOMMAND | MF_GRAYED);
  705.         }
  706.         else
  707.         {
  708.             uFlags = (MF_BYCOMMAND | MF_ENABLED);
  709.         }
  710.  
  711.         // Disable menu items until a movie is opened
  712.         EnableMenuItem(hMenu, IDM_FILE_CLOSE, uFlags);
  713.         EnableMenuItem(hMenu, IDM_MOVIE_STOP, uFlags);
  714.         EnableMenuItem(hMenu, IDM_MOVIE_PLAY, uFlags);
  715.         EnableMenuItem(hMenu, IDM_MOVIE_PAUSE, uFlags);
  716.     }
  717. }
  718.  
  719.  
  720. /*****************************Private*Routine******************************\
  721. * VideoCd_OnGraphNotify
  722. *
  723. * This is where we get any notifications from the filter graph.
  724. *
  725. \**************************************************************************/
  726. void
  727. VideoCd_OnGraphNotify(
  728.     int stream
  729.     )
  730. {
  731.     long    lEventCode;
  732.  
  733.     lEventCode = pMpegMovie->GetMovieEventCode();
  734.  
  735.     switch(lEventCode)
  736.     {
  737.         case EC_FULLSCREEN_LOST:
  738.             SetPlayButtonsEnableState();
  739.             break;
  740.  
  741.         case EC_USERABORT:
  742.         case EC_ERRORABORT:
  743.             VcdPlayerStopCmd();
  744.             SetPlayButtonsEnableState();
  745.             break;
  746.  
  747.         case EC_COMPLETE:
  748.             VcdPlayerRewindCmd();
  749.             break;
  750.  
  751.         default:
  752.             break;
  753.     }
  754. }
  755.  
  756.  
  757. /*****************************Private*Routine******************************\
  758. * VideoCd_OnNotify
  759. *
  760. * This is where we get the text for tooltips
  761. *
  762. \**************************************************************************/
  763. LRESULT
  764. VideoCd_OnNotify(
  765.     HWND hwnd,
  766.     int idFrom,
  767.     NMHDR FAR* pnmhdr
  768.     )
  769. {
  770.     switch(pnmhdr->code)
  771.     {
  772.         case TTN_NEEDTEXT:
  773.             {
  774.                 LPTOOLTIPTEXT   lpTt;
  775.                 lpTt = (LPTOOLTIPTEXT)pnmhdr;
  776.  
  777.                 LoadString(hInst, (UINT) lpTt->hdr.idFrom, lpTt->szText,
  778.                     sizeof(lpTt->szText));
  779.             }
  780.             break;
  781.     }
  782.  
  783.     return 0;
  784. }
  785.  
  786.  
  787. /******************************Public*Routine******************************\
  788. * SetPlayButtonsEnableState
  789. *
  790. * Sets the play buttons enable state to match the state of the current
  791. * cdrom device.  See below...
  792. *
  793. *
  794. *                 VCD Player buttons enable state table
  795. * --------------------------------------------------------------------
  796. * -E=Enabled D=Disabled      - Play - Pause - Eject - Stop  - Other -
  797. * --------------------------------------------------------------------
  798. * -Disk in use               -  D   -  D    -  D    -   D   -   D   -
  799. * --------------------------------------------------------------------
  800. * -No video cd or data cdrom -  D   -  D    -  E    -   D   -   D   -
  801. * --------------------------------------------------------------------
  802. * -Video cd (playing)        -  D   -  E    -  E    -   E   -   E   -
  803. * --------------------------------------------------------------------
  804. * -Video cd (paused)         -  E   -  D    -  E    -   E   -   E   -
  805. * --------------------------------------------------------------------
  806. * -Video cd (stopped)        -  E   -  D    -  E    -   D   -   E   -
  807. * --------------------------------------------------------------------
  808. *
  809. \**************************************************************************/
  810. void
  811. SetPlayButtonsEnableState(
  812.     void
  813.     )
  814. {
  815.     BOOL    fEnable, fPress;
  816.     BOOL    fVideoCdLoaded;
  817.  
  818.     /*
  819.     ** Do we have a video cd loaded.
  820.     */
  821.     if(g_State & (VCD_NO_CD | VCD_DATA_CD_LOADED | VCD_IN_USE))
  822.     {
  823.         fVideoCdLoaded = FALSE;
  824.     }
  825.     else
  826.     {
  827.         fVideoCdLoaded = TRUE;
  828.     }
  829.  
  830.     /*
  831.     ** Do the play button
  832.     */
  833.     if(fVideoCdLoaded
  834.         && ((g_State & VCD_STOPPED) || (g_State & VCD_PAUSED)))
  835.     {
  836.         fEnable = TRUE;
  837.     }
  838.     else
  839.     {
  840.         fEnable = FALSE;
  841.     }
  842.     SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_PLAY, fEnable);
  843.  
  844.     /*
  845.     ** Do the stop button
  846.     */
  847.     if(fVideoCdLoaded
  848.         && ((g_State & VCD_PLAYING) || (g_State & VCD_PAUSED)))
  849.     {
  850.         fEnable = TRUE;
  851.     }
  852.     else
  853.     {
  854.         fEnable = FALSE;
  855.     }
  856.     SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_STOP, fEnable);
  857.  
  858.     /*
  859.     ** Do the pause button
  860.     */
  861.     if(fVideoCdLoaded && (g_State & VCD_PLAYING))
  862.     {
  863.         fEnable = TRUE;
  864.     }
  865.     else
  866.     {
  867.         fEnable = FALSE;
  868.     }
  869.     SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_PAUSE, fEnable);
  870.  
  871.     /*
  872.     ** Do the remaining buttons
  873.     */
  874.     /*
  875.     ** Do the fullscreen button
  876.     */
  877.     fPress = (fVideoCdLoaded && IsFullScreenMode());
  878.  
  879.     SendMessage(g_hwndToolbar, TB_CHECKBUTTON, IDM_FULL_SCREEN, MAKELONG(fPress,0));
  880.     SendMessage(g_hwndToolbar, TB_ENABLEBUTTON, IDM_FULL_SCREEN, fVideoCdLoaded && (g_State & VCD_PLAYING));
  881. }
  882.  
  883.  
  884. /*****************************Private*Routine******************************\
  885. * GetAdjustedClientRect
  886. *
  887. * Calculate the size of the client rect and then adjusts it to take into
  888. * account the space taken by the toolbar and status bar.
  889. *
  890. \**************************************************************************/
  891. void
  892. GetAdjustedClientRect(
  893.     RECT *prc
  894.     )
  895. {
  896.     RECT    rcTool;
  897.  
  898.     GetClientRect(hwndApp, prc);
  899.  
  900.     if(IsWindowVisible(g_hwndToolbar))
  901.     {
  902.         GetWindowRect(g_hwndToolbar, &rcTool);
  903.         prc->top += (rcTool.bottom - rcTool.top);
  904.     }
  905. }
  906.  
  907.  
  908. /******************************Public*Routine******************************\
  909. * IdStr
  910. *
  911. * Loads the given string resource ID into the passed storage.
  912. *
  913. \**************************************************************************/
  914. LPCTSTR
  915. IdStr(
  916.     int idResource
  917.     )
  918. {
  919.     static TCHAR    chBuffer[ STR_MAX_STRING_LEN ];
  920.  
  921.     if(LoadString(hInst, idResource, chBuffer, STR_MAX_STRING_LEN) == 0)
  922.     {
  923.         return g_szEmpty;
  924.     }
  925.  
  926.     return chBuffer;
  927. }
  928.  
  929.  
  930. /******************************Public*Routine******************************\
  931. * SetFullScreenMode
  932. *
  933. \**************************************************************************/
  934. void
  935. SetFullScreenMode(BOOL bMode)
  936. {
  937.     static HMENU hMenu=0;
  938.     static LONG  lStyle=0;
  939.     static int xs=0, ys=0, cxs=0, cys=0;
  940.  
  941.     // Defer until we activate the movie
  942.     if(pMpegMovie->GetStateMovie() != State_Running)
  943.     {
  944.         if(bMode == TRUE)
  945.             return;
  946.     }
  947.  
  948.     m_bFullScreen = bMode;
  949.  
  950.     HDC hdcScreen = GetDC(NULL);
  951.     int cx = GetDeviceCaps(hdcScreen,HORZRES);
  952.     int cy = GetDeviceCaps(hdcScreen,VERTRES);
  953.     ReleaseDC(NULL, hdcScreen);
  954.  
  955.     pMpegMovie->SetFullScreenMode(bMode);
  956.  
  957.     if(bMode)
  958.     {
  959.         hMenu = GetMenu(hwndApp);
  960.         lStyle = GetWindowStyle(hwndApp);
  961.  
  962.         WINDOWPLACEMENT wp;
  963.         wp.length = sizeof(WINDOWPLACEMENT);
  964.         GetWindowPlacement(hwndApp, &wp);
  965.         xs = wp.rcNormalPosition.left;
  966.         ys = wp.rcNormalPosition.top;
  967.         cxs = wp.rcNormalPosition.right - xs;
  968.         cys = wp.rcNormalPosition.bottom - ys;
  969.         ShowWindow(g_hwndToolbar, SW_HIDE);
  970.         SetMenu(hwndApp, NULL);
  971.         SetWindowLong(hwndApp, GWL_STYLE, WS_POPUP | WS_VISIBLE);
  972.         SetWindowPos(hwndApp, HWND_TOP, 0, 0, cx, cy, SWP_NOACTIVATE);
  973.         ShowCursor(FALSE);
  974.     }
  975.     else
  976.     {
  977.         ShowCursor(TRUE);
  978.         ShowWindow(g_hwndToolbar, SW_SHOW);
  979.         SetMenu(hwndApp, hMenu);
  980.         SetWindowLong(hwndApp, GWL_STYLE, lStyle);
  981.         SetWindowPos(hwndApp, HWND_TOP, xs, ys, cxs, cys, SWP_NOACTIVATE);
  982.     }
  983. }
  984.  
  985.  
  986. /******************************Public*Routine******************************\
  987. * IsFullScreenMode()
  988. *
  989. \**************************************************************************/
  990. BOOL
  991. IsFullScreenMode()
  992. {
  993.     return m_bFullScreen;
  994. }
  995.  
  996.